package com.crm.service.before_sale.impl;

import com.crm.dao.before_sale.SaleChanceDAO;
import com.crm.dao.client.ClientInfoDao;
import com.crm.dao.client.ContactDao;
import com.crm.dao.permission.UserInfoDAO;
import com.crm.excel.upload.SaleChanceExcel;
import com.crm.exception.ServiceException;
import com.crm.pojo.ClientInfo;
import com.crm.pojo.Contact;
import com.crm.pojo.SaleChance;
import com.crm.service.before_sale.SaleChanceService;
import com.crm.vo.Result;
import com.crm.vo.SaleChanceVO;
import com.sun.org.apache.regexp.internal.RE;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional(rollbackFor = Exception.class)
public class SaleChanceServiceimpl implements SaleChanceService {
    @Autowired
    private SaleChanceDAO saleChanceDAO;
    @Autowired
    private ClientInfoDao clientInfoDao;
    @Autowired
    private  ContactDao contactDao;

    /**
     * 销售机会 高级查询,
     * 可以根据SaleChance的任何属性查询，没有属性则查询全部
     * @param saleChance
     * @param curpage
     * @param pagesize
     * @param expectStartTime
     * @param expectEndTime
     * @param createStartTime
     * @param createEndTime
     * @param updateStartTime
     * @param updateEndTime
     * @return
     */
    @Override
    public List<SaleChance> advanceSaleChance(SaleChance saleChance, int curpage, int pagesize, BigDecimal minDay,BigDecimal maxDay,
                                              BigDecimal minMoney,BigDecimal maxMoney,Date expectStartTime, Date expectEndTime, Date createStartTime, Date createEndTime, Date updateStartTime, Date updateEndTime) {
        Assert.notNull(saleChance);
        PageRequest pageRequest = new PageRequest(curpage-1,pagesize,Sort.Direction.DESC, "updateDate");
        @SuppressWarnings("unchecked")
        Page<SaleChance> result = saleChanceDAO.findAll(new Specification<SaleChance>() {
            @Override
            public Predicate toPredicate(Root<SaleChance> root, CriteriaQuery<?> arg1, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<>();
               //根据以下条件查询
                //1.机会主题
                if (!StringUtils.isEmpty(saleChance.getChanceTheme())){
                    list.add(cb.like(root.get("chanceTheme").as(String.class),"%" + saleChance.getChanceTheme() + "%"));
                }
                //2.进展阶段
                if (!StringUtils.isEmpty(saleChance.getStage())){
                    list.add(cb.like(root.get("stage").as(String.class),"%" + saleChance.getStage() + "%"));
                }
                //3.状态
                if(!StringUtils.isEmpty(saleChance.getState())){
                    list.add(cb.like(root.get("state").as(String.class),"%" + saleChance.getState() + "%"));
                }
                //4.阶段停留
                //min-stage
                if(minDay != null){
                    list.add(cb.greaterThanOrEqualTo(root.get("stageRemain").as(BigDecimal.class),minDay));
                }
                //max-satge
                if(maxDay != null){
                    list.add(cb.lessThanOrEqualTo(root.get("stageRemain").as(BigDecimal.class),maxDay));
                }
                //5.类型
                if(!StringUtils.isEmpty(saleChance.getType())){
                    list.add(cb.like(root.get("type").as(String.class),"%" + saleChance.getType() + "%"));
                }
                //6.客户名称
                if(saleChance.getClientId() != null){
                    list.add(cb.equal(root.get("clientId").as(BigDecimal.class),saleChance.getClientId()));
                }
                //7.客户联系人
                if(saleChance.getContactId() != null){
                    list.add(cb.equal(root.get("contactId").as(BigDecimal.class),saleChance.getContactId()));
                }
                //8.提供人
                if(saleChance.getUserId() != null){
                    list.add(cb.equal(root.get("userId").as(BigDecimal.class),saleChance.getUserId()));
                }
                //9.预期金额
                //min-money
                if(minMoney != null){
                    list.add(cb.greaterThanOrEqualTo(root.get("expectMoney").as(BigDecimal.class),minMoney));
                }
                //max-money
                if(maxMoney != null){
                    list.add(cb.lessThanOrEqualTo(root.get("expectMoney").as(BigDecimal.class),maxMoney));
                }

                //11.星标
                if(!StringUtils.isEmpty(saleChance.getAsterisk())){
                    list.add(cb.equal(root.get("asterisk").as(String.class), saleChance.getAsterisk()));
                }
                //12.优先级
                if(!StringUtils.isEmpty(saleChance.getPossibility())){
                    list.add(cb.like(root.get("priority").as(String.class),"%" + saleChance.getPriority() + "%"));
                }
                //13.预计签单日期
                //开始日期
                if (createStartTime != null){
                    list.add(cb.greaterThanOrEqualTo(root.get("findTime").as(Date.class),createStartTime));
                }
                //结束日期
                if (createEndTime != null){
                    list.add(cb.lessThanOrEqualTo(root.get("findTime").as(Date.class),createEndTime));
                }
                //14.意向产品
                if(!StringUtils.isEmpty(saleChance.getIntentRpoduct())){
                    list.add(cb.like(root.get("intentRpoduct").as(String.class),"%" + saleChance.getIntentRpoduct() + "%"));
                }
                //15.替代品威胁
                if(!StringUtils.isEmpty(saleChance.getSuccedaneum())){
                    list.add(cb.like(root.get("succedaneum").as(String.class),"%" + saleChance.getSuccedaneum()));
                }
                //16.需求概要
                if(!StringUtils.isEmpty(saleChance.getOutlineNeed())){
                    list.add(cb.like(root.get("outlineNeed").as(String.class),"%" + saleChance.getOutlineNeed() + "%"));
                }
                //17.阶段备注
                if(!StringUtils.isEmpty(saleChance.getRemarks())){
                    list.add(cb.like(root.get("remarks").as(String.class),"%" + saleChance.getRemarks() + "%"));
                }
                //18.更新日期
                //开始日期
                if(updateStartTime!= null){
                    list.add(cb.greaterThanOrEqualTo(root.get("updateDate").as(Date.class),updateStartTime));
                }
                //结束日期
                if(updateEndTime != null){
                    list.add(cb.lessThanOrEqualTo(root.get("updateDate").as(Date.class),updateEndTime));
                }
                //没有被删除
                list.add(cb.notLike(root.get("saleChanceIsDel").as(String.class),"是"));

                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        },pageRequest);
        List<SaleChance> list = result.getContent();
        return list;
    }

    /**
     * 销售机会 高级查询
     * 获得销售机会的总数量
     * @param saleChance
     * @param expectStartTime
     *  @param expectEndTime
     * @param createStartTime
     * @param createEndTime
     * @param updateStartTime
     * @param updateEndTime
     * @return
     */
    @Override
    public Long advanceSaleChanceCount(SaleChance saleChance, BigDecimal minDay,BigDecimal maxDay,
                                       BigDecimal minMoney,BigDecimal maxMoney, Date expectStartTime, Date expectEndTime, Date createStartTime, Date createEndTime,  Date updateStartTime, Date updateEndTime) {
        Assert.notNull(saleChance);
        Long count = saleChanceDAO.count(new Specification<SaleChance>() {
            @Override
            public Predicate toPredicate(Root<SaleChance> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<>();
                //根据以下条件查询
                //1.机会主题
                if (!StringUtils.isEmpty(saleChance.getChanceTheme())){
                    list.add(cb.like(root.get("chanceTheme").as(String.class),"%" + saleChance.getChanceTheme() + "%"));
                }
                //2.进展阶段
                if (!StringUtils.isEmpty(saleChance.getStage())){
                    list.add(cb.like(root.get("stage").as(String.class),"%" + saleChance.getStage() + "%"));
                }
                //3.状态
                if(!StringUtils.isEmpty(saleChance.getState())){
                    list.add(cb.like(root.get("state").as(String.class),"%" + saleChance.getState() + "%"));
                }
                //4.阶段停留
                //min-stage
                if(minDay != null){
                    list.add(cb.greaterThanOrEqualTo(root.get("stageRemain").as(BigDecimal.class),minDay));
                }
                //max-satge
                if(maxDay != null){
                    list.add(cb.lessThanOrEqualTo(root.get("stageRemain").as(BigDecimal.class),maxDay));
                }
                //5.类型
                if(!StringUtils.isEmpty(saleChance.getType())){
                    list.add(cb.like(root.get("type").as(String.class),"%" + saleChance.getType() + "%"));
                }
                //6.客户名称
                if(saleChance.getClientId() != null){
                    list.add(cb.equal(root.get("clientId").as(BigDecimal.class),saleChance.getClientId()));
                }
                //7.客户联系人
                if(saleChance.getContactId() != null){
                    list.add(cb.equal(root.get("contactId").as(BigDecimal.class),saleChance.getContactId()));
                }
                //8.提供人
                if(saleChance.getUserId() != null){
                    list.add(cb.equal(root.get("userId").as(BigDecimal.class),saleChance.getUserId()));
                }
                //9.预期金额
                //min-money
                if(minMoney != null){
                    list.add(cb.greaterThanOrEqualTo(root.get("expectMoney").as(BigDecimal.class),minMoney));
                }
                //max-money
                if(maxMoney != null){
                    list.add(cb.lessThanOrEqualTo(root.get("expectMoney").as(BigDecimal.class),maxMoney));
                }

                //11.星标
                if(!StringUtils.isEmpty(saleChance.getAsterisk())){
                    list.add(cb.equal(root.get("asterisk").as(String.class), saleChance.getAsterisk()));
                }
                //12.优先级
                if(!StringUtils.isEmpty(saleChance.getPossibility())){
                    list.add(cb.like(root.get("priority").as(String.class),"%" + saleChance.getPriority() + "%"));
                }
                //13.预计签单日期
                //开始日期
                if (createStartTime != null){
                    list.add(cb.greaterThanOrEqualTo(root.get("findTime").as(Date.class),createStartTime));
                }
                //结束日期
                if (createEndTime != null){
                    list.add(cb.lessThanOrEqualTo(root.get("findTime").as(Date.class),createEndTime));
                }
                //14.意向产品
                if(!StringUtils.isEmpty(saleChance.getIntentRpoduct())){
                    list.add(cb.like(root.get("intentRpoduct").as(String.class),"%" + saleChance.getIntentRpoduct() + "%"));
                }
                //15.替代品威胁
                if(!StringUtils.isEmpty(saleChance.getSuccedaneum())){
                    list.add(cb.like(root.get("succedaneum").as(String.class),"%" + saleChance.getSuccedaneum()));
                }
                //16.需求概要
                if(!StringUtils.isEmpty(saleChance.getOutlineNeed())){
                    list.add(cb.like(root.get("outlineNeed").as(String.class),"%" + saleChance.getOutlineNeed() + "%"));
                }
                //17.阶段备注
                if(!StringUtils.isEmpty(saleChance.getRemarks())){
                    list.add(cb.like(root.get("remarks").as(String.class),"%" + saleChance.getRemarks() + "%"));
                }
                //18.更新日期
                //开始日期
                if(updateStartTime!= null){
                    list.add(cb.greaterThanOrEqualTo(root.get("updateDate").as(Date.class),updateStartTime));
                }
                //结束日期
                if(updateEndTime != null){
                    list.add(cb.lessThanOrEqualTo(root.get("updateDate").as(Date.class),updateEndTime));
                }
                //没有被删除
                list.add(cb.notLike(root.get("saleChanceIsDel").as(String.class),"是"));

                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        });
        return count;
    }

    /**
     * 获取销售机会总数量
     * @return
     */
    @Override
    public Long getSaleChanceExistCount() {
        try {
            return saleChanceDAO.getSaleChanceExistCount();
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(e);
        }
    }

    /**
     * 分页展示销售机会列表
     * @param curpage
     * @param rows
     * @return
     */
    @Override
    public List<SaleChanceVO> queryAllSaleChanceList(int curpage, int rows) {
        try {
            PageRequest pageRequest = new PageRequest(curpage-1,rows);
            List<SaleChanceVO> list = saleChanceDAO.queryAllSaleChanceByPage(pageRequest);

            return list;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(e);
        }
    }

    /**
     * 删除销售机会
     * @param chId
     * @return
     */
    @Override
    public Result deleteSaleChanceById(Long chId) throws ServiceException{
        try {
            saleChanceDAO.deleteSaleChanceById(chId);
            return Result.SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return  new Result(e);
        }
    }

    /**
     * 根据客户id查找客户名称
     * @param clientId
     * @return
     */
    @Override
    public String getClientName(Long clientId) {
        try {
            if (clientId != null){
                ClientInfo clientInfo = clientInfoDao.findOne(clientId);
                return clientInfo.getCname();
            }else {
                return "";
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("Sorry,查询客户失败！");
        }
    }

    /**
     * 根据客户联系人id查找联系人姓名
     * @param contactId
     * @return
     */
    @Override
    public String getContactName(Long contactId) {
        try {
            if(contactId != null){
                Contact contact = contactDao.findOne(contactId);
                return contact.getContactName();
            }else {
                return "";
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("Sorry,查询客户联系人失败！");
        }
    }

    /**
     * 添加一个销售机会
     * @param asterisk
     * @param chanceTheme
     * @param clientId
     * @param contactId
     * @param userId
     * @param expectDate
     * @param expectMoney
     * @param findTime
     * @param intentRpoduct
     * @param outlineNeed
     * @param possibility
     * @param priority
     * @param remarks
     * @param stage
     * @param stageRemain
     * @param state
     * @param succedaneum
     * @param type
     * @param updateDate
     * @return
     */
    @Override
    public Result addSaleChance(String asterisk,String chanceTheme, BigDecimal clientId, BigDecimal contactId,
                                BigDecimal userId, Date expectDate, BigDecimal expectMoney, Date findTime,
                                String intentRpoduct,String outlineNeed, String possibility, String priority,
                                String remarks, String stage, BigDecimal stageRemain,
                                String state, String succedaneum, String type, Date updateDate) {
        try {
            SaleChance saleChance = new SaleChance();
            saleChance.setAsterisk(asterisk);
            saleChance.setChanceTheme(chanceTheme);
            saleChance.setExpectDate(expectDate);
            saleChance.setExpectMoney(expectMoney);
            saleChance.setFindTime(new Date());
            saleChance.setIntentRpoduct(intentRpoduct);
            saleChance.setOutlineNeed(outlineNeed);
            saleChance.setPossibility(possibility);
            saleChance.setPriority(priority);
            saleChance.setRemarks(remarks);
            saleChance.setSaleChanceIsDel("否");
            saleChance.setStage(stage);
            saleChance.setStageRemain(stageRemain);
            saleChance.setState(state);
            saleChance.setSuccedaneum(succedaneum);
            saleChance.setType(type);
            saleChance.setUpdateDate(new Date());
            saleChance.setUserId(userId);
            saleChance.setContactId(contactId);
            saleChance.setClientId(clientId);
            saleChanceDAO.save(saleChance);
            return Result.SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return   new Result("添加失败");
        }
    }

    /**
     * 编辑销售机会信息
     *
     * @return
     */
    @Override
    public Result editSaleChance(SaleChance saleChance) {
        try {


            saleChance.setUpdateDate(new Date());
            saleChanceDAO.save(saleChance);
            return Result.SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return new Result("Sorry,编辑失败！");
        }

    }

    /**
     * 获取所有销售机会主题名称
     * @return
     */
    @Override
    public List<SaleChance> getSaleChanceTheme() {
        List<SaleChance> list = new ArrayList<>();
        saleChanceDAO.findAll().forEach(e -> list.add(e));
        return list;
    }

    /**
     * 根据id获取一个机会主题
     * @param chId
     * @return
     */
    @Override
    public String getSaleChanceThemeById(Long chId) {
        SaleChance saleChance = saleChanceDAO.findOne(chId);
        return saleChance.getChanceTheme();
    }

    /**
     * 查找所有机会
     * （转成excel表格）
     * @return
     */
    @Override
    public List<SaleChance> findAll() {
        return (List<SaleChance>) saleChanceDAO.findAll();
    }

    /**
     * 通过excel导入销售机会
     * @param file
     * @param uploadWay
     * @return
     */
    @Override
    public Result uploadExcelSaleChance(MultipartFile file, String uploadWay) {
        //创建处理EXCEL的类
        SaleChanceExcel saleChanceExcel = new SaleChanceExcel();
        //解析excel，获取上传的事件单,拿到所有信息
        List<SaleChance> saleChanceList = saleChanceExcel.getExcelInfo(file);
        //信息集合不为空，保存到数据库中
        if(saleChanceList != null && !saleChanceList.isEmpty()){
            if ("新建式导入".equals(uploadWay)) {
                //新建式导入，直接创建
                for (SaleChance saleChance : saleChanceList){
                    saleChanceDAO.save(saleChance);
                }
            }else {
                //覆盖式导入，相同得则覆盖，不相同得新建
                for (SaleChance saleChance : saleChanceList){
                    List<SaleChance> list = saleChanceDAO.getSaleChanceByTheme(saleChance.getChanceTheme());
                    if (list != null && list.size() != 0){
                        for (SaleChance saleChance1: list){
                            saleChance.setChId(saleChance1.getChId());
                            saleChanceDAO.save(saleChance);
                        }
                    }else {
                        saleChanceDAO.save(saleChance);
                    }

                }
            }
            return Result.SUCCESS;
        }else {
            return new Result("上传失败！");
        }
    }
}

